import pcap
import threading
import time

class Sniffer(threading.Thread):
    def __init__(self,interface=None,snaplen=4096,promiscmode=True,callback=None):
        '''
        Sniffer class
            usage:    mysniffer = Sniffer(iface, snaplen, promismode, callback)
                string   iface         = Capturing interface name (ex: "eth0")
                int      snaplen       = Maximum bytes captured by packets (ex: 4096)
                bool     promiscmode   = Promiscuous mode (True or False)
                function callback      = Function or method called for each frame captured
        '''
        threading.Thread.__init__(self)
        self.__capture = None                   # pcap instance
        self.__interface = interface            # capture interface
        self.__snaplen = snaplen                # maxbytes to capture per packet
        self.__promiscmode = promiscmode        # is interface in promiscuous mode
        self.__callback = callback              # callback function to trigger
        self.__running = False                  # is the Thread running ?

    def startCapture(self):
        '''Starts the capture process'''
        self.__capture = pcap.pcapObject()
        self.__capture.open_live(self.__interface,self.__snaplen,self.__promiscmode,0)
        self.__capture.setnonblock(1)
    
    def stopCapture(self):
        '''Stops the capture process'''
        self.__capture = None
        
    def isCaptureActive(self):
        '''Returns True if the capture is active (self.__capture != None), else returns False'''
        if type(self.__capture) is pcap.pcapObject:
            return True
        else:
            return False 
    
    def isRunning(self):
        '''Returns True if the thread is running (self.__running = True)'''
        return self.__running
    
    def stop(self):
        '''Stops the capture if active and then stops the thread'''
        if self.isCaptureActive():
            self.stopCapture()
        self.__running = False
        
    def run(self):
        '''Class main loop'''
        self.__running = True
        while self.isRunning():
            if self.isCaptureActive():
                try:
                    self.__capture.dispatch(1,self.__callback)
                except:
                    pass
            else:
                time.sleep(0.1)
